package com.dragon.mmochat.message;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.model.enumType.MmochatOtherSystemSettingType;
import com.dragon.mmochat.model.map.MmochatMap;
import com.dragon.mmochat.model.map.MmochatMapHint;
import com.dragon.mmochat.model.role.MmochatNpc;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.model.role.MmochatTempNpc;
import com.dragon.mmochat.service.MmochatBattleService;
import com.skymobi.buffer.SkymobiBuffer;
import com.skymobi.message.SkymobiProtocolMessage;

public class Mmochat_1_1S extends SkymobiProtocolMessage {
	Integer hallState = null;
	MmochatPlayer me = null;
	int line = 0;
	MmochatMap map = null;
	Map<Integer, MmochatPlayer> sceenRoles = new ConcurrentHashMap<Integer, MmochatPlayer>();
	String enterMapMsg = null; // 对话框内容
	String enterMapText = null; // 文本框内容
	boolean needCallBack = false; // 是否需要答复server消息已收到

	public Mmochat_1_1S() {
		setMsgCode(MmochatConstant.MSGCODE_MMOCHAT_S_1_1);
	}

	@Override
	protected void encodeBody(SkymobiBuffer out) {
		if (me != null) {
			if (needCallBack) {
				out.put((byte) 1);
			} else {
				out.put((byte) 0);
			}
			if (hallState == null) {
				out.put((byte) 0);
				out.putUnsignedShort(0);
			} else {
				out.put((byte) 1);
				out.putUnsignedShort(hallState);
			}
			out.putInt(map.getMapId());
			out.putInt(map.getMapDataId());
			if (map.isWalkToBattle()) {
				out.put((byte) 1);
			} else {
				out.put((byte) 0);
			}
			if (map.isHasWeather()) {
				out.put((byte) map.getCurWeather().getValue());
			} else {
				out.put((byte) 0);
			}
			out.put((byte) line);
			out.putPrefixedString(map.getMapName(), 1);
			// put me
			out.putUnsignedInt(me.getStateValue(null));
			out.putInt(me.getRealRoleId());
			out.putShort((short) me.getX());
			out.putShort((short) me.getY());
			out.put((byte) me.getRoleType().getValue());
			out.putPrefixedString(me.getName(), 2);
			if (me.getCurChenHao() == null) {
				out.put((byte) 0);
			} else {
				out.putPrefixedString(me.getCurChenHaoInfo(), 1);
			}
			out.put((byte) Math.min(100, (100 * me.getCurBlood() / Math.max(1,
					me.getTotalBlood()))));
			out.put((byte) Math.min(100, (100 * me.getCurSprit() / Math.max(1,
					me.getTotalSprit()))));
			out.put((byte) Math.min(100, (100L * me.getExp() / Math.max(1,
					MmochatBattleService.getHumanExpNeedToUplevel(
							me.getLevel(), me.getLife_turn())))));

			// put others
			int roleNum = sceenRoles.size();
			out.putShort((short) roleNum);
			for (MmochatPlayer role : sceenRoles.values()) {
				out.putInt(role.getRoleId());
				out.putShort((short) role.getX());
				out.putShort((short) role.getY());
				out.put((byte) role.getRoleType().getValue());
				out.putUnsignedInt(role.getStateValue(me));
				out.putPrefixedString(role.getName(), 2);
				if (me
						.getOtherSystemSettingByType(MmochatOtherSystemSettingType.不显示他人等级)) {
					if (role.getCurChenHao() == null) {
						out.put((byte) 0);
					} else {
						out.putPrefixedString(role.getCurChenHaoInfo(), 1);
					}
				} else {
					// 显示他人等级
					out.putPrefixedString(role.getLevelInfo(), 1);
				}

			}

			// put npc
			List<MmochatNpc> npcs = null;
			if (map.getLineNpcMap(line) != null) {
				npcs = new ArrayList<MmochatNpc>(map.getLineNpcMap(line)
						.values());
			}
			if (npcs == null) {
				out.putShort((short) 0);
			} else {
				out.putShort((short) npcs.size());
				for (MmochatNpc npc : npcs) {
					me.addTmpNpc(npc.getNpcId());
					out.putInt(npc.getNpcId());
					if (npc instanceof MmochatTempNpc) {
						out.put((byte) 1);
					} else {
						out.put((byte) 0);
					}
					out.put((byte) npc.getTaskStateValue(me));
					out.putShort(npc.getX());
					out.putShort(npc.getY());
					out.putUnsignedShort(npc.getBmpType().getValue());
					out.put((byte) npc.getFace().getValue());
					out.putPrefixedString(npc.getName(), 1);
				}
			}
			// put hints
			out.putShort((short) map.getHints().size());
			for (MmochatMapHint hint : map.getHints()) {
				out.putShort((short) hint.getX());
				out.putShort((short) hint.getY());
				out.putUnsigned((short) hint.getType().getColor().getRed());
				out.putUnsigned((short) hint.getType().getColor().getGreen());
				out.putUnsigned((short) hint.getType().getColor().getBlue());
				out.putPrefixedString(hint.getHint(), 1);
			}

			if (enterMapMsg == null) {
				out.putShort((short) 0);
			} else {
				out.putPrefixedString(enterMapMsg, 2);
			}

			if (enterMapText == null) {
				out.putShort((short) 0);
			} else {
				out.putPrefixedString(enterMapText, 2);
			}
		}
	}

	public void setHallState(int hallState) {
		this.hallState = hallState;
	}

	public void setMe(MmochatPlayer me) {
		this.me = me;
	}

	public void setLine(int line) {
		this.line = line;
	}

	public void setSceenRoles(Map<Integer, MmochatPlayer> sceenRoles) {
		this.sceenRoles = new ConcurrentHashMap<Integer, MmochatPlayer>(
				sceenRoles);
	}

	public void addSceenRole(MmochatPlayer role) {
		sceenRoles.put(role.getRoleId(), role);
	}

	public void setHallState(Integer hallState) {
		this.hallState = hallState;
	}

	public void setEnterMapMsg(String enterMapMsg) {
		this.enterMapMsg = enterMapMsg;
	}

	public String getEnterMapMsg() {
		return enterMapMsg;
	}

	public void setMap(MmochatMap map) {
		this.map = map;
	}

	public void setNeedCallBack(boolean needCallBack) {
		this.needCallBack = needCallBack;
		if (needCallBack) {
			me.setLockTrans(true);
		}
	}

	public void setEnterMapText(String enterMapText) {
		this.enterMapText = enterMapText;
	}

}